/*
 * Copyright (c) 2021, Peter Abeles. All Rights Reserved.
 *
 * This file is part of BoofCV (http://boofcv.org).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package boofcv.alg.filter.convolve;

import boofcv.alg.InputSanityCheck;
import boofcv.alg.filter.convolve.border.ConvolveJustBorder_General_IL;
import boofcv.alg.filter.convolve.border.ConvolveJustBorder_General_SB;
import boofcv.struct.border.ImageBorder_F32;
import boofcv.struct.border.ImageBorder_IL_F32;
import boofcv.struct.border.ImageBorder_IL_S32;
import boofcv.struct.border.ImageBorder_S32;
import boofcv.struct.convolve.Kernel1D_F32;
import boofcv.struct.convolve.Kernel1D_S32;
import boofcv.struct.convolve.Kernel2D_F32;
import boofcv.struct.convolve.Kernel2D_S32;
import boofcv.struct.image.*;

/**
 * <p>
 * Convolves a kernel across an image and handles the image border using the specified method.
 * </p>
 * <p>Automatically generated by GenerateConvolveImage. DO NOT MODIFY</p>
 *
 * @author Peter Abeles
 */
@SuppressWarnings({"ForLoopReplaceableByForEach", "Duplicates"})
public class ConvolveImage {

	/**
	 * Performs a horizontal 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void horizontal( Kernel1D_F32 kernel,
								  GrayF32 input, GrayF32 output, ImageBorder_F32 border ) {
		InputSanityCheck.checkReshape(input, output);

		if (BOverrideConvolveImage.invokeNativeHorizontal(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.horizontal(kernel, input, output);
		ConvolveJustBorder_General_SB.horizontal(kernel, border, output);
	}

	/**
	 * Performs a vertical 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void vertical( Kernel1D_F32 kernel,
								  GrayF32 input, GrayF32 output, ImageBorder_F32 border ) {
		InputSanityCheck.checkReshape(input, output);

		if (BOverrideConvolveImage.invokeNativeVertical(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.vertical(kernel, input, output);
		ConvolveJustBorder_General_SB.vertical(kernel, border, output);
	}

	/**
	 * Performs a 2D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void convolve( Kernel2D_F32 kernel,
								  GrayF32 input, GrayF32 output, ImageBorder_F32 border ) {
		InputSanityCheck.checkReshape(input, output);

		if (BOverrideConvolveImage.invokeNativeConvolve(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.convolve(kernel, input, output);
		ConvolveJustBorder_General_SB.convolve(kernel, border, output);
	}

	/**
	 * Performs a horizontal 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void horizontal( Kernel1D_F32 kernel,
								  InterleavedF32 input, InterleavedF32 output, ImageBorder_IL_F32 border ) {
		InputSanityCheck.checkReshapeB(input, output);

		if (BOverrideConvolveImage.invokeNativeHorizontal(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.horizontal(kernel, input, output);
		ConvolveJustBorder_General_IL.horizontal(kernel, border, output);
	}

	/**
	 * Performs a vertical 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void vertical( Kernel1D_F32 kernel,
								  InterleavedF32 input, InterleavedF32 output, ImageBorder_IL_F32 border ) {
		InputSanityCheck.checkReshapeB(input, output);

		if (BOverrideConvolveImage.invokeNativeVertical(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.vertical(kernel, input, output);
		ConvolveJustBorder_General_IL.vertical(kernel, border, output);
	}

	/**
	 * Performs a 2D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void convolve( Kernel2D_F32 kernel,
								  InterleavedF32 input, InterleavedF32 output, ImageBorder_IL_F32 border ) {
		InputSanityCheck.checkReshapeB(input, output);

		if (BOverrideConvolveImage.invokeNativeConvolve(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.convolve(kernel, input, output);
		ConvolveJustBorder_General_IL.convolve(kernel, border, output);
	}

	/**
	 * Performs a horizontal 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void horizontal( Kernel1D_S32 kernel,
								  GrayU8 input, GrayI16 output, ImageBorder_S32<GrayU8> border ) {
		InputSanityCheck.checkReshape(input, output);

		if (BOverrideConvolveImage.invokeNativeHorizontal(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.horizontal(kernel, input, output);
		ConvolveJustBorder_General_SB.horizontal(kernel, border, output);
	}

	/**
	 * Performs a vertical 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void vertical( Kernel1D_S32 kernel,
								  GrayU8 input, GrayI16 output, ImageBorder_S32<GrayU8> border ) {
		InputSanityCheck.checkReshape(input, output);

		if (BOverrideConvolveImage.invokeNativeVertical(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.vertical(kernel, input, output);
		ConvolveJustBorder_General_SB.vertical(kernel, border, output);
	}

	/**
	 * Performs a 2D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void convolve( Kernel2D_S32 kernel,
								  GrayU8 input, GrayI16 output, ImageBorder_S32<GrayU8> border ) {
		InputSanityCheck.checkReshape(input, output);

		if (BOverrideConvolveImage.invokeNativeConvolve(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.convolve(kernel, input, output);
		ConvolveJustBorder_General_SB.convolve(kernel, border, output);
	}

	/**
	 * Performs a horizontal 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void horizontal( Kernel1D_S32 kernel,
								  InterleavedU8 input, InterleavedI16 output, ImageBorder_IL_S32<InterleavedU8> border ) {
		InputSanityCheck.checkReshapeB(input, output);

		if (BOverrideConvolveImage.invokeNativeHorizontal(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.horizontal(kernel, input, output);
		ConvolveJustBorder_General_IL.horizontal(kernel, border, output);
	}

	/**
	 * Performs a vertical 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void vertical( Kernel1D_S32 kernel,
								  InterleavedU8 input, InterleavedI16 output, ImageBorder_IL_S32<InterleavedU8> border ) {
		InputSanityCheck.checkReshapeB(input, output);

		if (BOverrideConvolveImage.invokeNativeVertical(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.vertical(kernel, input, output);
		ConvolveJustBorder_General_IL.vertical(kernel, border, output);
	}

	/**
	 * Performs a 2D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void convolve( Kernel2D_S32 kernel,
								  InterleavedU8 input, InterleavedI16 output, ImageBorder_IL_S32<InterleavedU8> border ) {
		InputSanityCheck.checkReshapeB(input, output);

		if (BOverrideConvolveImage.invokeNativeConvolve(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.convolve(kernel, input, output);
		ConvolveJustBorder_General_IL.convolve(kernel, border, output);
	}

	/**
	 * Performs a horizontal 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void horizontal( Kernel1D_S32 kernel,
								  GrayU8 input, GrayS32 output, ImageBorder_S32<GrayU8> border ) {
		InputSanityCheck.checkReshape(input, output);

		if (BOverrideConvolveImage.invokeNativeHorizontal(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.horizontal(kernel, input, output);
		ConvolveJustBorder_General_SB.horizontal(kernel, border, output);
	}

	/**
	 * Performs a vertical 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void vertical( Kernel1D_S32 kernel,
								  GrayU8 input, GrayS32 output, ImageBorder_S32<GrayU8> border ) {
		InputSanityCheck.checkReshape(input, output);

		if (BOverrideConvolveImage.invokeNativeVertical(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.vertical(kernel, input, output);
		ConvolveJustBorder_General_SB.vertical(kernel, border, output);
	}

	/**
	 * Performs a 2D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void convolve( Kernel2D_S32 kernel,
								  GrayU8 input, GrayS32 output, ImageBorder_S32<GrayU8> border ) {
		InputSanityCheck.checkReshape(input, output);

		if (BOverrideConvolveImage.invokeNativeConvolve(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.convolve(kernel, input, output);
		ConvolveJustBorder_General_SB.convolve(kernel, border, output);
	}

	/**
	 * Performs a horizontal 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void horizontal( Kernel1D_S32 kernel,
								  InterleavedU8 input, InterleavedS32 output, ImageBorder_IL_S32<InterleavedU8> border ) {
		InputSanityCheck.checkReshapeB(input, output);

		if (BOverrideConvolveImage.invokeNativeHorizontal(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.horizontal(kernel, input, output);
		ConvolveJustBorder_General_IL.horizontal(kernel, border, output);
	}

	/**
	 * Performs a vertical 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void vertical( Kernel1D_S32 kernel,
								  InterleavedU8 input, InterleavedS32 output, ImageBorder_IL_S32<InterleavedU8> border ) {
		InputSanityCheck.checkReshapeB(input, output);

		if (BOverrideConvolveImage.invokeNativeVertical(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.vertical(kernel, input, output);
		ConvolveJustBorder_General_IL.vertical(kernel, border, output);
	}

	/**
	 * Performs a 2D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void convolve( Kernel2D_S32 kernel,
								  InterleavedU8 input, InterleavedS32 output, ImageBorder_IL_S32<InterleavedU8> border ) {
		InputSanityCheck.checkReshapeB(input, output);

		if (BOverrideConvolveImage.invokeNativeConvolve(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.convolve(kernel, input, output);
		ConvolveJustBorder_General_IL.convolve(kernel, border, output);
	}

	/**
	 * Performs a horizontal 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void horizontal( Kernel1D_S32 kernel,
								  GrayS16 input, GrayI16 output, ImageBorder_S32<GrayS16> border ) {
		InputSanityCheck.checkReshape(input, output);

		if (BOverrideConvolveImage.invokeNativeHorizontal(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.horizontal(kernel, input, output);
		ConvolveJustBorder_General_SB.horizontal(kernel, border, output);
	}

	/**
	 * Performs a vertical 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void vertical( Kernel1D_S32 kernel,
								  GrayS16 input, GrayI16 output, ImageBorder_S32<GrayS16> border ) {
		InputSanityCheck.checkReshape(input, output);

		if (BOverrideConvolveImage.invokeNativeVertical(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.vertical(kernel, input, output);
		ConvolveJustBorder_General_SB.vertical(kernel, border, output);
	}

	/**
	 * Performs a 2D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void convolve( Kernel2D_S32 kernel,
								  GrayS16 input, GrayI16 output, ImageBorder_S32<GrayS16> border ) {
		InputSanityCheck.checkReshape(input, output);

		if (BOverrideConvolveImage.invokeNativeConvolve(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.convolve(kernel, input, output);
		ConvolveJustBorder_General_SB.convolve(kernel, border, output);
	}

	/**
	 * Performs a horizontal 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void horizontal( Kernel1D_S32 kernel,
								  InterleavedS16 input, InterleavedI16 output, ImageBorder_IL_S32<InterleavedS16> border ) {
		InputSanityCheck.checkReshapeB(input, output);

		if (BOverrideConvolveImage.invokeNativeHorizontal(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.horizontal(kernel, input, output);
		ConvolveJustBorder_General_IL.horizontal(kernel, border, output);
	}

	/**
	 * Performs a vertical 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void vertical( Kernel1D_S32 kernel,
								  InterleavedS16 input, InterleavedI16 output, ImageBorder_IL_S32<InterleavedS16> border ) {
		InputSanityCheck.checkReshapeB(input, output);

		if (BOverrideConvolveImage.invokeNativeVertical(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.vertical(kernel, input, output);
		ConvolveJustBorder_General_IL.vertical(kernel, border, output);
	}

	/**
	 * Performs a 2D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void convolve( Kernel2D_S32 kernel,
								  InterleavedS16 input, InterleavedI16 output, ImageBorder_IL_S32<InterleavedS16> border ) {
		InputSanityCheck.checkReshapeB(input, output);

		if (BOverrideConvolveImage.invokeNativeConvolve(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.convolve(kernel, input, output);
		ConvolveJustBorder_General_IL.convolve(kernel, border, output);
	}

	/**
	 * Performs a horizontal 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void horizontal( Kernel1D_S32 kernel,
								  GrayS32 input, GrayS32 output, ImageBorder_S32<GrayS32> border ) {
		InputSanityCheck.checkReshape(input, output);

		if (BOverrideConvolveImage.invokeNativeHorizontal(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.horizontal(kernel, input, output);
		ConvolveJustBorder_General_SB.horizontal(kernel, border, output);
	}

	/**
	 * Performs a vertical 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void vertical( Kernel1D_S32 kernel,
								  GrayS32 input, GrayS32 output, ImageBorder_S32<GrayS32> border ) {
		InputSanityCheck.checkReshape(input, output);

		if (BOverrideConvolveImage.invokeNativeVertical(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.vertical(kernel, input, output);
		ConvolveJustBorder_General_SB.vertical(kernel, border, output);
	}

	/**
	 * Performs a 2D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void convolve( Kernel2D_S32 kernel,
								  GrayS32 input, GrayS32 output, ImageBorder_S32<GrayS32> border ) {
		InputSanityCheck.checkReshape(input, output);

		if (BOverrideConvolveImage.invokeNativeConvolve(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.convolve(kernel, input, output);
		ConvolveJustBorder_General_SB.convolve(kernel, border, output);
	}

	/**
	 * Performs a horizontal 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void horizontal( Kernel1D_S32 kernel,
								  InterleavedS32 input, InterleavedS32 output, ImageBorder_IL_S32<InterleavedS32> border ) {
		InputSanityCheck.checkReshapeB(input, output);

		if (BOverrideConvolveImage.invokeNativeHorizontal(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.horizontal(kernel, input, output);
		ConvolveJustBorder_General_IL.horizontal(kernel, border, output);
	}

	/**
	 * Performs a vertical 1D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void vertical( Kernel1D_S32 kernel,
								  InterleavedS32 input, InterleavedS32 output, ImageBorder_IL_S32<InterleavedS32> border ) {
		InputSanityCheck.checkReshapeB(input, output);

		if (BOverrideConvolveImage.invokeNativeVertical(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.vertical(kernel, input, output);
		ConvolveJustBorder_General_IL.vertical(kernel, border, output);
	}

	/**
	 * Performs a 2D convolution across the image.
	 *
	 * @param input The original image. Not modified.
	 * @param output Where the resulting image is written to. Modified.
	 * @param kernel The kernel that is being convolved. Not modified.
	 * @param border How the image borders are handled.
	 */
	public static void convolve( Kernel2D_S32 kernel,
								  InterleavedS32 input, InterleavedS32 output, ImageBorder_IL_S32<InterleavedS32> border ) {
		InputSanityCheck.checkReshapeB(input, output);

		if (BOverrideConvolveImage.invokeNativeConvolve(kernel, input, output, border))
			return;

		border.setImage(input);
		ConvolveImageNoBorder.convolve(kernel, input, output);
		ConvolveJustBorder_General_IL.convolve(kernel, border, output);
	}

}
